const {
    Op
} = require('sequelize')
const Moment = require('moment')


class Dao {
    /* --------------------- 增 -------------------- */
    // 插入数据
    async create(params, Table) {
        const v = new Table()
        Object.keys(params).forEach(function (key) {
            v[key] = params[key]
        })
        v.created_at = Moment().format('YYYY-MM-DD HH:mm:ss')
        v.updated_at = Moment().format('YYYY-MM-DD HH:mm:ss')
        try {
            const res = await v.save()
            return [null, res]
        } catch (err) {
            return [err, null]
        }
    }

    async findOrCreate(params, Table) {

        try {
            const [row, created] = await Table.findOrCreate({
                where: params,
                defaults: {
                    created_at: Moment().format('YYYY-MM-DD HH:mm:ss'),
                    updated_at: Moment().format('YYYY-MM-DD HH:mm:ss')
                }
            })
            if (created) {
                return [null, row]
            } else {
                return ['标签已存在', null]
            }
        } catch (err) {
            return [err, null]
        }
    }

    /* --------------------- 删 -------------------- */
    // 根据id 删除
    async deleteById(id, Table) {
        try {
            const res = await Table.destroy({ // res: 返回 删除条数 例：1
                where: {
                    id
                }
            })
            if (res) {
                return [null, '删除成功']
            } else {
                return ['查无此条目，无法删除！', null]
            }
        } catch (err) {
            return [err, null]
        }
    }

    // 删除 多参数
    async delete(params, Table) {
        await Table.destroy({
            where: params
        })
    }

    /* --------------------- 改 -------------------- */
    async update(params, Table) {
        const v = await Table.findByPk(params.id)
        if (!v) {
            return ['查无匹配id,请检查id!', null]
        }

        Object.keys(params).forEach(key => {
            if (key === 'id') return // id 唯一不可赋值 会报错
            v[key] = params[key]
        })
        // v.created_at = Moment().format('YYYY-MM-DD HH:mm:ss')
        v.updated_at = Moment().format('YYYY-MM-DD HH:mm:ss')

        try {
            const res = await v.save()
            return [null, res]
        } catch (err) {
            return [err, null]
        }
    }


    /* --------------------- 查 -------------------- */
    // id查找全部
    async findById(id, Table) {
        const v = await Table.findAll({
            where: {
                id
            }
        })
        if (v === null) {
            return ['查询不匹配', null]
        } else {
            return [null, v]
        }
    }

    // 查 id 一个 详情
    async findOneById(id, Table) {
        const v = await Table.findOne({
            where: {
                id
            }
        })
        if (v === null) {
            return ['查询不匹配', null]
        } else {
            return [null, v]
        }
    }


    // 比对
    async check(params, Table) {
        const v = await Table.findOne({
            where: params
        })
        if (v === null) {
            return ['查询不匹配', null]
        } else {
            return [null, v]
        }
    }

    async list2({
        params = {},
        attributes = {},
        sample = [], // like 查找
        all = false, // 查找全部 默认false
    }, Table) {

        // 获取页码 和 每页条数
        let {
            page = 1, page_size = 10 // 默认每页10条
        } = params

        // 删除以下键值对
        delete params.page
        delete params.page_size

        // 匹配
        if (sample[1]) { // [name , key]

            params[sample[0]] = {
                [Op.like]: `%${sample[1]}%`
            }
        }

        // all 查全部数据
        if (all) {
            page = null,
                page_size = null
        }

        try {
            const res = await Table.findAndCountAll({
                where: params,
                attributes,
                limit: null, //每页10条
                offset: (page - 1) * page_size,
                order: [
                    ['created_at', 'DESC']
                ]
            })
            const data = {
                rows: res.rows,
                meta: {
                    current_page: parseInt(page), // 当前页数
                    page_size, // 每页条目
                    count: res.count, // 条目总数
                    total_pages: Math.ceil(res.count / 10), // 总页数
                }
            }
            return [null, data]
        } catch (err) {
            return [err, null]
        }
    }

    // 查询 列表 模糊查询
    async list(params = {}, Table, sample = []) {
        // 获取页码 和 每页条数
        const {
            page = 1, page_size = 10
        } = params

        // 删除以下键值对
        delete params.page
        delete params.page_size

        // 匹配
        if (sample[1]) { // [name , key]

            params[sample[0]] = {
                [Op.like]: `%${sample[1]}%`
            }
        }

        try {
            const res = await Table.findAndCountAll({
                where: params,
                attributes: {},
                limit: page_size, //每页10条
                offset: (page - 1) * page_size,
                order: [
                    ['created_at', 'DESC']
                ]
            })
            const data = {
                rows: res.rows,
                meta: {
                    current_page: parseInt(page), // 当前页数
                    page_size, // 每页条目
                    count: res.count, // 条目总数
                    total_pages: Math.ceil(res.count / 10), // 总页数
                }
            }
            return [null, data]
        } catch (err) {
            return [err, null]
        }
    }

}

module.exports = new Dao